package org.andromda.cartridges.jsf.portlet.myfaces.tomahawk;

import java.io.IOException;

import javax.faces.context.ResponseWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.myfaces.renderkit.html.util.HtmlBufferResponseWriterWrapper;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlResponseWriterImpl;

/**
 * Extends the default MyFaces Tomahawk {DefaultAddResource} class in order to
 * allow injection of the required content into portlets.
 * 
 * @author Chad Brandon
 */
public class AddResource extends
		org.apache.myfaces.renderkit.html.util.DefaultAddResource {
	/**
	 * @see org.apache.myfaces.renderkit.html.util.DefaultAddResource#writeResponse(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public void writeResponse(final HttpServletRequest request,
			final HttpServletResponse response) throws IOException {
		final ResponseWriter writer = new HtmlResponseWriterImpl(
				response.getWriter(),
				HtmlRendererUtils.selectContentType(null),
				response.getCharacterEncoding());
		writer.write(originalResponse.toString());
	}

	/**
	 * Overridden to allow injection of the required content for portlets (i.e.
	 * which have no <head/>, <body/>, etc tags).
	 * 
	 * @see org.apache.myfaces.renderkit.html.util.DefaultAddResource#writeWithFullHeader(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public void writeWithFullHeader(final HttpServletRequest request,
			final HttpServletResponse response) throws IOException {
		if (!parserCalled) {
			throw new IOException("Method parseResponse has to be called first");
		}

		final ResponseWriter writer = new HtmlResponseWriterImpl(
				response.getWriter(),
				HtmlRendererUtils.selectContentType(request.getHeader("accept")),
				response.getCharacterEncoding());

		// - insert anything that was supposed to go into the <head/>
		headerInsertPosition = 0;
		final HtmlBufferResponseWriterWrapper headContents = HtmlBufferResponseWriterWrapper
				.getInstance(writer);
		for (final PositionedInfo positionedInfo : (Iterable<PositionedInfo>) getHeaderBeginInfos()) {
			headContents.write("\n");

			if (!(positionedInfo instanceof WritablePositionedInfo)) {
				throw new IllegalStateException("positionedInfo of type : "
						+ positionedInfo.getClass().getName());
			}
			((WritablePositionedInfo) positionedInfo).writePositionedInfo(
					response, headContents);
		}
		originalResponse.insert(headerInsertPosition, headContents.toString());

		// TODO: fix this
		/*
		 * StringBuilder buf = new StringBuilder(); Set bodyInfos =
		 * getBodyOnloadInfos(); if (bodyInfos.size() > 0) { int i = 0; for
		 * (Iterator it = getBodyOnloadInfos().iterator(); it.hasNext();) {
		 * AttributeInfo positionedInfo = (AttributeInfo) it.next(); if (i == 0)
		 * { buf.append(positionedInfo.getAttributeName()); buf.append("=\""); }
		 * buf.append(positionedInfo.getAttributeValue());
		 * 
		 * i++; }
		 * 
		 * buf.append("\""); originalResponse.insert(bodyInsertPosition - 1, " "
		 * + buf.toString()); }
		 */

		// insert all the items that want to go immediately after the <body>
		// tag.
		final HtmlBufferResponseWriterWrapper afterBodyContents = HtmlBufferResponseWriterWrapper
				.getInstance(writer);

		for (final PositionedInfo positionedInfo : (Iterable<PositionedInfo>) getBodyEndInfos()) {
			afterBodyContents.write("\n");

			if (!(positionedInfo instanceof WritablePositionedInfo)) {
				throw new IllegalStateException("positionedInfo of type : "
						+ positionedInfo.getClass().getName());
			}
			((WritablePositionedInfo) positionedInfo).writePositionedInfo(
					response, afterBodyContents);
		}

		originalResponse.insert(headContents.toString().length() + 1,
				afterBodyContents.toString());
	}
}
